<?php
/**
 * This file is part of the Anota project.
 * 2011-2012 Fernando Garcia Huerta <fgarciahue@uoc.edu>
 * 
 * UOC - FUNDAMENTOS DE INFORMÁTICA EN ENTORNOS BIOINFORMÁTICOS - PEC2
 */

/**
 * Main configuration file.
 *
 * @package    Anota
 * @subpackage application
 * @author     Fernando Garcia Huerta <fgarciahue@uoc.edu>
 */
class AnotaConfig
{

    protected
    $conn = null,                 // database connection object
    $user = null,                 // user session object
    $rootDir = null,              // root directory of application
    $libDir = null,               // lib directory of applictaion
    $images = null,               // images directory
    $cgiDir = null,               // cgis directory
    $cgis = array(),              // list of available cgis
    $global_template = null,      // global layout of application
    $display_options = array(),   // geneid display options
    $output_options = array(),    // geneid output options
    $strand_options = array(),    // geneid strand options
    $engine_options = array(),    // geneid engine options
    $paramfileDir = null,         // geneid param directory
    $paramfile_options = array(), // geneid list of param options
    $defaults = array();          // form defaults
    static public
    $CONVERT_NAME = 'convert',    // convert cgi command
    $GFF2PS_NAME = 'gff2ps.v98l', // gff2ps cgi command
    $GENEID_NAME = 'geneid';      // geneid cgi command
    
    /**
     * Constructor.
     *
     * @param string    $rootDir    The project root directory
     */
    public function __construct($rootDir = null)
    {
        // ensures correct php configuration
        ini_set('magic_quotes_runtime', 'off');
        
        // creates session object
        $this->user = new AnotaUser();

        // main directories
        $this->rootDir = realpath($rootDir);
        $this->libDir = realpath(dirname(__FILE__));
        $this->images = $this->rootDir . DIRECTORY_SEPARATOR . 'images';
        
        // main layout
        $this->global_template = $this->rootDir . DIRECTORY_SEPARATOR . 'templateGlobal.php';

        // rest of setup
        $this->setupDatabase();
        $this->setupCgis();
        $this->setupDisplayOptions();
        $this->setupOutputOptions();
        $this->setupStrandOptions();
        $this->setupEngineOptions();
        $this->setupParamfileOptions();
        $this->setupDefaults();
    }

    /**
     * Setups database connection.
     * 
     *  - load configuration from: libDir->database.config
     */
    protected function setupDatabase()
    {
        // read config file
        $lines = file($this->libDir . DIRECTORY_SEPARATOR. 'database.config', FILE_IGNORE_NEW_LINES || FILE_SKIP_EMPTY_LINES);        
        // open and stores database connection
        $this->conn = mysql_connect(trim($lines[0]), trim($lines[2]), trim($lines[3])) or die ();
        mysql_select_db(trim($lines[1]),$this->conn) or die();
    }
    
    /**
     * Setups cgis locations
     */
    protected function setupCgis()
    {
        $this->cgiDir = $this->rootDir . DIRECTORY_SEPARATOR . 'cgi-bin';
        $this->cgis[self::$CONVERT_NAME] = self::$CONVERT_NAME;
        $this->cgis[self::$GFF2PS_NAME] = $this->cgiDir . DIRECTORY_SEPARATOR . self::$GFF2PS_NAME;
        $this->cgis[self::$GENEID_NAME] = $this->cgiDir . DIRECTORY_SEPARATOR . self::$GENEID_NAME;
    }

    /**
     * Setups geneid display options
     */
    protected function setupDisplayOptions()
    {
        $this->display_options = array(
            'b' => 'Display best <strong>Start codons</strong> found on sequence',
            'd' => 'Display best <strong>Donor sites</strong> found on sequence',
            'a' => 'Display best <strong>Acceptor sites</strong> found on sequence',
            'e' => 'Display best <strong>Stop codons</strong> found on sequence',
            'f' => 'Display best <strong>First exons</strong> found on sequence',
            'i' => 'Display best <strong>Internal exons</strong> found on sequence',
            't' => 'Display best <strong>Terminal exons</strong> found on sequence',
            's' => 'Display best <strong>Single genes</strong> found on sequence',
            'x' => 'Display best <strong>exons (all)</strong> found on sequence',
            'z' => 'Display <strong>Open Reading Frames</strong> found on sequence (See -Z)',
            'D' => 'Display <strong>Genomic sequence in predicted genes</strong>'
        );
    }

    /**
     * Setups geneid output options
     */
    protected function setupOutputOptions()
    {        
        $this->output_options = array(
            0 => array('option' => '', 'label' => 'geneid format'),
            1 => array('option' => 'G', 'label' => 'gff format'),
            2 => array('option' => 'X', 'label' => 'Extended format (gff or geneid)'),
            3 => array('option' => 'M', 'label' => 'XML output (see -m)'),
            4 => array('option' => 'm', 'label' => 'See DTD for XML output')
        );
    }

    /**
     * Setups geneid strand options
     */
    protected function setupStrandOptions()
    {
        $this->strand_options = array(
            0 => array('option' => '', 'label' => 'Predictions in both strands of sequence'),
            1 => array('option' => 'W', 'label' => 'Predictions only in forward strand of sequence'),
            2 => array('option' => 'C', 'label' => 'Predictions only in reverse strand of sequence')
        );
    }

    /**
     * Setups geneid engine options
     */
    protected function setupEngineOptions()
    {
        $this->engine_options = array(
            0 => array('option' => 'o', 'label' => 'Only signal and exon prediction (gene assembling disabled)'),
            1 => array('option' => 'F', 'label' => 'Force prediction of a complete gene'),
            2 => array('option' => 'O', 'label' => 'Only gene assembling (exons provided from file)'),
            3 => array('option' => 'Z', 'label' => 'Switch ORF searching on')
        );
    }

    /**
     *  setup geneid param file options
     */
    protected function setupParamfileOptions()
    {
        $this->paramfileDir = $this->cgiDir . DIRECTORY_SEPARATOR . 'param';
        $files = scandir($this->paramfileDir);
        foreach ($files as $file)
        {
            if ($file == '.' || $file == '..')
            {
                unset($file);
            } else
            {
                $param_file = array();
                $param_file['relative_path_file'] = 'cgi-bin'.DIRECTORY_SEPARATOR.'param'.DIRECTORY_SEPARATOR.$file;
                $param_file['id'] = 'param_option_' . str_replace('.', '_', $file);
                $param_file['label'] = str_replace('.param', '', $file);

                $this->paramfile_options[$file] = $param_file;
            }
        }
        unset($files);
    }

    /**
     * Setups form default options
     */
    protected function setupDefaults()
    {
        $this->defaults['param_file'] = 'human1iso.param';
        $this->defaults['output_option'] = 0;
        $this->defaults['strand_option'] = 0;
        $this->defaults['engine_option'] = 0;
    }

    
    /**
     * Returns database connection
     * 
     * @return object
     */
    public function getConn()
    {
        return $this->conn;
    }
    
    /**
     * Returns user for session management
     * 
     * @return AnotaUser
     */
    public function getUser()
    {
        return $this->user;
    }

    /**
     * Returns the full path for the requested cgi.
     * 
     * @param   string $name
     * @return  string
     */
    public function getCgi($name)
    {
        if (!isset($this->cgis[$name]))
        {
            throw new InvalidArgumentException(sprintf('There is no configuration for the "%s" cgi.', $name));
        }

        return $this->cgis[$name];
    }

    /**
     * Returns geneid display options
     * 
     * @return type array()
     */
    public function getDisplayOptions()
    {
        return $this->display_options;
    }

    /**
     * Returns geneid output options
     * 
     * @return array()
     */
    public function getOutputOptions()
    {
        return $this->output_options;
    }

    /**
     * Returns geneid strand options
     * 
     * @return array()
     */
    public function getStrandOptions()
    {
        return $this->strand_options;
    }

    /**
     * Returns geneid engine options
     * 
     * @return array()
     */
    public function getEngineOptions()
    {
        return $this->engine_options;
    }

    /**
     * Returns geneid param file options
     * 
     * @return array()
     */
    public function getParamfileOptions()
    {
        return $this->paramfile_options;
    }

    /**
     * Returns geneid paramfile full path
     * 
     * @return string
     */
    public function getParamfileDir()
    {
        return $this->paramfileDir;
    }

    /**
     * Returns images full path
     * 
     * @return string
     */
    public function getImagesDir()
    {
        return $this->images;
    }

    /**
     * Returns the value for the requested default param.
     * 
     * @param   string $name
     * @return  string
     */
    public function getDefault($name)
    {
        if (!isset($this->defaults[$name]))
        {
            throw new InvalidArgumentException(sprintf('There is no value for the "%s" default.', $name));
        }

        return $this->defaults[$name];
    }

    /**
     * Returns application root dir
     * 
     * @return string
     */
    public function getRootDir()
    {
        return $this->rootDir;
    }

    /**
     * Returns global template name
     * 
     * @return string
     */
    public function getGlobalTemplate()
    {
        return $this->global_template;
    }

}